﻿using Newtonsoft.Json.Linq;
using QCloudApiService.Center;
using QCloudApiService.Module;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using UplopadQCloudDemo.Models;

/// <summary>
/// Upload video to qclould api
/// you should config your 
///  <add key="SecretId" value="[SecretId]"/>
///  <add key = "SecretKey" value="[YourSecretKey]"/>'
///  in Web.congfig file.
///  you can find them in qclould admin console.
///  more info: https://www.qcloud.com/document/product/266/1033
/// </summary>
namespace UplopadQCloudDemo.Controllers
{
    public class VideoController : ApiController
    {
        [HttpPost]
        public void Post([FromBody]string value)
        {

        }

        [HttpPost]
        public void CallBack()
        {
            var jsonString = System.Web.HttpUtility.UrlDecode(HttpContext.Current.Request.Form.ToString(), System.Text.Encoding.UTF8);

            var model = jsonString.JsonStringToObj<CallBackModel>();

            // To Log qclould video infor...
        }

        [HttpPost]

        public async Task<string> Upload()
        {
            var fileId = "";
            try
            {

                if (!Request.Content.IsMimeMultipartContent())
                {
                    throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
                }

                var root = HttpContext.Current.Server.MapPath("/UploadFiles/");
                if (!Directory.Exists(HttpContext.Current.Server.MapPath("~/UploadFiles/")))
                {
                    Directory.CreateDirectory(HttpContext.Current.Server.MapPath("~/UploadFiles/"));
                }

                var provider = new MultipartFormDataStreamProvider(root);

                var sb = new StringBuilder(); // Holds the response body

                await Request.Content.ReadAsMultipartAsync(provider);
                foreach (var file in provider.FileData)
                {
                    var orfilename = file.Headers.ContentDisposition.FileName.TrimStart('"').TrimEnd('"');
                    var fileinfo = new FileInfo(file.LocalFileName);
                    var fileExt = orfilename.Substring(orfilename.LastIndexOf('.'));

                    fileinfo.CopyTo(Path.Combine(root, fileinfo.Name + fileExt), true);
                    var fileName = root + fileinfo.Name + fileExt;

                    fileId = UploadVideoFile(fileinfo, fileName);
                }
                return fileId;
            }
            catch (Exception ex)
            {
                return "";
            }
        }
        private string UploadVideoFile(FileInfo fileinfo, string path)
        {

            var fileId = string.Empty;
            var config = new SortedDictionary<string, object>(StringComparer.Ordinal);

            config["RequestMethod"] = "POST";
            config["DefaultRegion"] = "gz";

            var module = new QCloudAPIModuleCenter(new Vod(), config);
            var requestParams = new SortedDictionary<string, object>(StringComparer.Ordinal);

            var fixDataSize = 1024 * 1024 * 5;  //每次上传字节数，可自定义[512*1024 ~ 5*1024*1024]
            var firstDataSize = 1024 * 512;    //最小片字节数（默认不变）
            var tmpDataSize = firstDataSize;
            var remainderSize = fileinfo.Length;
            var tmpOffset = 0;
            var code = 0;
            var flag = 0;

            var result = string.Empty;
            var fileSHA1 = path.ToSHA1();

            while (remainderSize > 0)
            {
                var par = new SortedDictionary<string, object>(StringComparer.Ordinal);
                par.Add("fileSha", fileSHA1);
                par.Add("fileType", path.Split('.').LastOrDefault());
                par.Add("fileName", DateTime.Now.ToString("yyyyMMddHHmmssffff"));
                par.Add("fileSize", fileinfo.Length);
                par.Add("dataSize", tmpDataSize);
                par.Add("offset", tmpOffset);
                par.Add("file", path);
                par.Add("isTranscode", "1");
                par.Add("isScreenshot", "1");
                par.Add("isWatermark", "1");

                par.Add("notifyUrl",  "[YourHost]/api/Video/CallBack");

                result = module.Call("MultipartUploadVodFile", par, path);

                var jsonResult = JObject.Parse(result);

                code = int.Parse(jsonResult["code"].ToString());

                if (code == -3002)
                {               //server retuen error，need reUplaod(offset=0, dataSize=512K)
                    tmpDataSize = firstDataSize;
                    tmpOffset = 0;
                    continue;
                }
                else if (code != 0)
                {
                    return null;
                }

                flag = int.Parse(jsonResult["flag"].ToString());
                if (flag == 1)
                {
                    fileId = jsonResult["fileId"].ToString();

                    fileinfo.Delete();
                    if (File.Exists(path))
                    {
                        File.Delete(path);
                    }
                    break;
                }
                else
                {
                    tmpOffset = int.Parse(jsonResult["offset"].ToString());
                    remainderSize = fileinfo.Length - tmpOffset;
                    if (fixDataSize < remainderSize)
                    {
                        tmpDataSize = fixDataSize;
                    }
                    else
                    {
                        tmpDataSize = (int)remainderSize;
                    }
                }

            }

            return fileId;
        }

        /// <summary>
        /// Get video info from qclould
        /// </summary>
        /// <param name="fileId">vodeo id that UploadVideoFile return</param>
        /// <returns></returns>
        [HttpGet]
        public static VodInfoModel GetInfo(string fileId)
        {
            var config = new SortedDictionary<string, object>(StringComparer.Ordinal);

            config["RequestMethod"] = "GET";
            config["DefaultRegion"] = "gz";

            var module = new QCloudAPIModuleCenter(new VodApi(), config);
            var requestParams = new SortedDictionary<string, object>(StringComparer.Ordinal);

            var par = new SortedDictionary<string, object>(StringComparer.Ordinal);
            par.Add("fileIds.1", fileId);

            var result = module.Call("DescribeVodInfo", par);

            return result.JsonStringToObj<VodInfoModel>();
        }
    }
}
